package org.example.sdk;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;
import org.jboss.logging.Logger;
import sun.misc.BASE64Encoder;


public class JitGatewayUtil {

    private static final Logger logger = Logger.getLogger(JitGatewayUtil.class);

    private static Map configMap = new HashMap<String, Object>();

    public static Map initConfig(Map<String, String> config){
        //Map configMap = new HashMap<String, Object>();
        configMap.put(JitConstant.ConfigConstant.KEY_AUTH_URL,
                config.get(JitConstant.ConfigConstant.KEY_AUTH_URL));
        configMap.put(JitConstant.ConfigConstant.KEY_APP_ID,
                config.get(JitConstant.ConfigConstant.KEY_APP_ID));
        configMap.put(JitConstant.ConfigConstant.KEY_QRCODE_AUTH, false);
        configMap.put(JitConstant.ConfigConstant.KEY_RANDOM_FROM, 1);
        configMap.put(JitConstant.ConfigConstant.KEY_ACCESS_CONTROL, false);
        configMap.put(JitConstant.ConfigConstant.KEY_GENERATEQRCODE_URL,
                config.get(JitConstant.ConfigConstant.KEY_GENERATEQRCODE_URL));
        configMap.put(JitConstant.ConfigConstant.KEY_QUERYQRCODESTATE_URL,
                config.get(JitConstant.ConfigConstant.KEY_QUERYQRCODESTATE_URL));
        return configMap;
    }
    public static JitResult random() {
        JitResult result = null;
        logger.info("random configmap中数据:" + configMap.toString());
        // randomFrom 1：调用应用服务器 2：调用网关
        if ((Integer) configMap.get(JitConstant.ConfigConstant.KEY_RANDOM_FROM) == 2) {
            logger.info("调用网关生成原文");
            result = generateRandomNumFromGagewayServer();
        } else {
            logger.info("调用应用服务器生成原文");
            result = generateRandomNumByApplication();
        }
        logger.info("生成原文结束,原文:" + result.getData());
        return result;
    }
    /**
     * 应用服务器产生认证原文(第二步 服务端产生认证原文)
     *
     * @return 认证原文
     */
    private static JitResult generateRandomNumByApplication() {
        JitResult result = new JitResult();
        String num = "1234567890abcdefghijklmnopqrstopqrstuvwxyz";
        int size = 6;
        char[] charArray = num.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < size; i++) {
            sb.append(charArray[((int) (Math.random() * 10000) % charArray.length)]);
        }
        result.setData(sb.toString());
        result.setSuccess(true);
        return result;
    }

    /**
     * 连接网关服务器产生认证原文
     *
     * @return 认证原文
     */
    private static JitResult generateRandomNumFromGagewayServer() {
        String errCode = null; //错误码
        String errDesc = null; //错误信息
        byte[] messagexml = null; //xml信息 请求
        String respMessageXml = null; //网关返回信息
        JitResult result = new JitResult();//返回的信息
        // 组装认证原文请求报文数据
        logger.info("组装认证原文请求报文数据开始");
        Document reqDocument = DocumentHelper.createDocument();
        Element root = reqDocument.addElement(JitConstant.CommonConstant.MSG_ROOT);
        Element requestHeadElement = root.addElement(JitConstant.CommonConstant.MSG_HEAD);
        Element requestBodyElement = root.addElement(JitConstant.CommonConstant.MSG_BODY);
        // 组装报文头信息
        requestHeadElement.addElement(JitConstant.CommonConstant.MSG_VSERSION).
                setText(JitConstant.CommonConstant.MSG_VSERSION_VALUE_10);
        requestHeadElement.addElement(JitConstant.CommonConstant.MSG_SERVICE_TYPE).
                setText(JitConstant.RandomConstant.MSG_SERVICE_TYPE_VALUE);
        // 组装报文体信息
        // 组装应用标识信息
        requestBodyElement.addElement(JitConstant.CommonConstant.MSG_APPID).
                setText(configMap.get(JitConstant.ConfigConstant.KEY_APP_ID).toString());
        try {
            // 将认证原文请求报文写入输出流开始
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            XMLWriter writer = new XMLWriter(outStream);
            writer.write(reqDocument);
            messagexml = outStream.toByteArray(); // 将认证原文请求报文写入输出流完毕
            logger.info("组装的原文请求数据为:");
            logger.info(outStream.toString());
        } catch (Exception e) {
            errDesc = "组装原文请求报文时出现异常";
            logger.error("组装原文请求报文时出现异常" + e.getMessage());
            result.setErrorMsg(errDesc);
            result.setSuccess(false);
            return result;
        }
        // 创建与网关的HTTP连接，发送认证原文请求报文，并接收认证原文响应报文
        // 创建与网关的HTTP连接开始
        logger.info("创建与网关的HTTP连接，开始发送认证原文请求报文");
        String authURL = (String) configMap.get(JitConstant.ConfigConstant.KEY_AUTH_URL);
        int statusCode = 500;
        HttpClient httpClient = new HttpClient();
        PostMethod postMethod = new PostMethod(authURL);
        postMethod.setRequestHeader("Connection", "close");
        // 设置报文传送的编码格式
        postMethod.setRequestHeader("Content-Type", "text/xml;charset=UTF-8");
        // 设置发送认证请求内容开始
        postMethod.setRequestBody(new ByteArrayInputStream(messagexml));
        try {
            // 执行postMethod 发送原文请求报文与网关通讯
            URL url = protocol(authURL);
            statusCode = httpClient.executeMethod(postMethod);
            if(url != null && "https".equals(url.getProtocol())){
                Protocol.unregisterProtocol("https");
            }
        } catch (Exception e) {
            errCode = String.valueOf(statusCode);
            errDesc = e.getMessage();
            logger.error("发送原文请求报文与网关出现异常：" + errDesc,e);
            postMethod.releaseConnection();
            httpClient.getHttpConnectionManager().closeIdleConnections(0);
            httpClient = null;
            /*String errorJdkMess = errorJdkMess(e);
            if(errorJdkMess != null){
                errDesc = errorJdkMess;
            }*/
            result.setErrorMsg(errDesc);
            result.setErrCode(errCode);
            result.setSuccess(false);
            return result;
        }
        logger.info("创建与网关的HTTP连接，发送认证原文请求报文结束,开始解析返回数据...");
        // 网关返回认证原文响应
        // 当返回200或500状态时处理业务逻辑
        if (statusCode == HttpStatus.SC_OK ||
                statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
            try {
                // 接收通讯报文并处理开始
                byte[] inputstr = postMethod.getResponseBody();
                ByteArrayInputStream byteinputStream = new ByteArrayInputStream(inputstr);
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                int ch = 0;
                try {
                    while ((ch = byteinputStream.read()) != -1) {
                        int upperCh = (char) ch;
                        outStream.write(upperCh);
                    }
                } catch (Exception e) {
                    logger.error("读取原文返回报文错误:"+e.getMessage(),e);
                    //errDesc = e.getMessage();
                    result.setErrorMsg("读取原文返回报文错误");
                    result.setSuccess(false);
                    return result;
                }
                // 200 表示返回处理成功
                if (statusCode == HttpStatus.SC_OK) {
                    respMessageXml = new String(outStream.toByteArray(),"UTF-8");
                    logger.info("请求原文返回报文为:");
                    logger.info(respMessageXml);
                } else {
                    // 500 表示返回失败，发生异常
                    errCode = String.valueOf(statusCode);
                    errDesc = new String(outStream.toByteArray());
                    logger.error("网关返回错误码500，错误信息为:" + errDesc);
                    result.setErrCode(errCode);
                    result.setErrorMsg(errDesc);
                    result.setSuccess(false);
                    return result;
                }
            } catch (IOException e) {
                errCode = String.valueOf(statusCode);
                errDesc = e.getMessage();
                logger.error("读取原文请求响应报文出现异常：" + errCode + "," + errDesc);
                result.setErrCode(errCode);
                result.setErrorMsg(errDesc);
                result.setSuccess(false);
                return result;
            } finally {
                if (httpClient != null) {
                    postMethod.releaseConnection();
                    httpClient.getHttpConnectionManager().closeIdleConnections(0);
                }
            }
        } else {
            logger.warn("the reppnse code is not 200 or 500.");
            result.setErrorMsg("the reppnse code is not 200 or 500.");
            result.setSuccess(false);
            return result;
        }
        // 接收并解析网关服务器返回的原文请求响应报文
        Document respDocument = null;
        Element headElement = null;
        Element bodyElement = null;
        //logger.info("开始解析网关服务器返回的原文请求响应报文");
        try {
            respDocument = DocumentHelper.parseText(respMessageXml);
        } catch (DocumentException e) {
            logger.error("解析网关返回的原文异常:" + e.getMessage());
            result.setErrorMsg("解析网关返回的xml原文异常");
            result.setSuccess(false);
            return result;
        }
        headElement = respDocument.getRootElement().element(JitConstant.CommonConstant.MSG_HEAD);
        bodyElement = respDocument.getRootElement().element(JitConstant.CommonConstant.MSG_BODY);
        //解析报文头开始
        if (headElement != null) {
            boolean state = Boolean.valueOf(
                    headElement.elementTextTrim(JitConstant.CommonConstant.MSG_MESSAGE_STATE));
            if (state) {
                errCode = headElement.elementTextTrim(JitConstant.CommonConstant.MSG_MESSAGE_CODE);
                errDesc = headElement.elementTextTrim(JitConstant.CommonConstant.MSG_MESSAGE_DESC);
                logger.error("向网关请求原文,解析报文头失败：" + errCode + "," + errDesc);
                result.setErrorMsg(errDesc);
                result.setErrCode(errCode);
                result.setSuccess(false);
                return result;
            }
        }
        //解析body原文
        Element originalElement = bodyElement.element(JitConstant.CommonConstant.MSG_ORIGINAL);
        String original = null;
        if (originalElement != null) {
            original = originalElement.getStringValue();
            result.setData(original);
            logger.info("向网关请求原文成功,生成原文：" + original);
        }
        // 返回认证原文
        result.setSuccess(true);
        return result;
    }

    public static AuthResult auth (JitGatewayUtilBean bean) {
        boolean isSuccess = true;// 成功标记
        String errCode = null;// 错误码
        String errDesc = null;// 错误信息
        String original_data_base64 = null;
        AuthResult result = new AuthResult(); //认证完成返回的信息

        logger.info("auth configmap中数据:" + configMap.toString());

        // 认证地址、应用标识
        String authURL = bean.getAuthURL();
        String appId = configMap.get(JitConstant.ConfigConstant.KEY_APP_ID).toString();
        // 校验应用标识或网关认证地址不可为空
        if (StringUtils.isBlank(appId) || StringUtils.isBlank(authURL)) {
            isSuccess = false;
            errDesc = "应用标识或网关认证地址不可为空";
            result.setSuccess(isSuccess);
            result.setErrDesc(errDesc);
            logger.error(errDesc);
            return result;
        }
        logger.info("应用标识及网关的认证地址读取成功！应用标识：" + appId + "认证地址：" + authURL);

        // 服务端验证认证原文
        if (isSuccess &&
                !JitConstant.AuthConstant.MSG_AUTH_MODE_QRCODE_VALUE.equalsIgnoreCase(bean.getAuthMode())) {
            if(StringUtils.isNotBlank(bean.getOriginal_data()) &&
                    StringUtils.isNotBlank(bean.getSigned_data()) &&
                    StringUtils.isNotBlank(bean.getOriginal_jsp())) {
                // 服务端验证认证原文
                if (!bean.getOriginal_data().equalsIgnoreCase(bean.getOriginal_jsp())) {
                    isSuccess = false;
                    errDesc = "服务端验证认证原文失败:客户端提供的认证原文与服务端的不一致";
                    result.setSuccess(isSuccess);
                    result.setErrDesc(errDesc);
                    logger.error(errDesc);
                    return result;
                } else {
                    // 生成随机密钥
                    original_data_base64 = new BASE64Encoder().encode(bean.getOriginal_jsp().getBytes());
                    logger.info("服务端验证认证原文:服务端验证认证原文成功！认证原文：" + bean.getOriginal_jsp());
                    logger.info("认证签名signed data请求包：" + bean.getSigned_data());
                }
            } else {
                isSuccess = false;
                errDesc = "服务端验证认证原文失败:证书认证数据不完整";
                result.setSuccess(isSuccess);
                result.setErrDesc(errDesc);
                logger.error(errDesc);
                return result;
            }
            //System.out.println("服务端验证认证原文结束");
        }
        //网关认证
        try {
            byte[] messagexml = null;
            if (isSuccess) {
                logger.info("组装认证请求报文开始");
                // 组装认证请求报文数据开始
                Document reqDocument = DocumentHelper.createDocument();
                Element root = reqDocument.addElement(JitConstant.CommonConstant.MSG_ROOT);
                Element requestHeadElement = root.addElement(JitConstant.CommonConstant.MSG_HEAD);
                Element requestBodyElement = root.addElement(JitConstant.CommonConstant.MSG_BODY);
                // 组装报文头信息 ,组装认证xml文件时，进行判断，如果配置调用应用服务器生成原文，则生成xml version版本为1.0，
                // 如果配置从网关生成原文，则生成xml version版本为1.1
                if( 2 == (Integer) configMap.get(JitConstant.ConfigConstant.KEY_RANDOM_FROM)) {
                    requestHeadElement.addElement(JitConstant.CommonConstant.MSG_VSERSION)
                            .setText(JitConstant.CommonConstant.MSG_VSERSION_VALUE_11);
                } else {
                    requestHeadElement.addElement(JitConstant.CommonConstant.MSG_VSERSION)
                            .setText(JitConstant.CommonConstant.MSG_VSERSION_VALUE_10);
                }
                // 服务类型
                requestHeadElement.addElement(JitConstant.CommonConstant.MSG_SERVICE_TYPE)
                        .setText(JitConstant.AuthConstant.MSG_SERVICE_TYPE_VALUE);
                // 组装报文体信息
                // 组装客户端信息
                Element clientInfoElement = requestBodyElement.addElement(JitConstant.AuthConstant.MSG_CLIENT_INFO);
                Element clientIPElement = clientInfoElement.addElement(JitConstant.AuthConstant.MSG_CLIENT_IP);
                clientIPElement.setText(bean.getRemoteAddr());
                // 组装应用标识信息
                requestBodyElement.addElement(JitConstant.CommonConstant.MSG_APPID).setText(appId);
                Element authenElement = requestBodyElement.addElement(JitConstant.AuthConstant.MSG_AUTH);
                Element authCredentialElement = authenElement.addElement(JitConstant.AuthConstant.MSG_AUTHCREDENTIAL);
                // 组装证书认证信息
                if (JitConstant.AuthConstant.MSG_AUTH_MODE_CERT_VALUE.equalsIgnoreCase(bean.getAuthMode())){
                    authCredentialElement.addAttribute(JitConstant.AuthConstant.MSG_AUTH_MODE,
                            JitConstant.AuthConstant.MSG_AUTH_MODE_CERT_VALUE);
                    authCredentialElement.addElement(JitConstant.AuthConstant.MSG_DETACH)
                            .setText(bean.getSigned_data());
                    authCredentialElement.addElement(JitConstant.CommonConstant.MSG_ORIGINAL)
                            .setText(original_data_base64);
                } else if (JitConstant.AuthConstant.MSG_AUTH_MODE_QRCODE_VALUE.equalsIgnoreCase(bean.getAuthMode())) {
                    authCredentialElement.addAttribute(JitConstant.AuthConstant.MSG_AUTH_MODE,
                            JitConstant.AuthConstant.MSG_AUTH_MODE_QRCODE_VALUE);
                    authCredentialElement.addElement(JitConstant.AuthConstant.MSG_TOKEN)
                            .setText(bean.getToken());
                    authCredentialElement.addElement(JitConstant.AuthConstant.MSG_QRCODE)
                            .setText(bean.getQrcode());
                }
                // 是否检查访问控制状态
                requestBodyElement.addElement(JitConstant.AuthConstant.MSG_ACCESS_CONTROL)
                        .setText(configMap.get(JitConstant.ConfigConstant.KEY_ACCESS_CONTROL).toString());

                // 组装属性查询列表信息
                Element attributesElement = requestBodyElement.addElement(JitConstant.AuthConstant.MSG_ATTRIBUTES);
                attributesElement.addAttribute(JitConstant.AuthConstant.MSG_ATTRIBUTE_TYPE,
                        JitConstant.AuthConstant.MSG_ATTRIBUTE_TYPE_ALL);
                try {
                    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                    XMLWriter writer = new XMLWriter(outStream);
                    writer.write(reqDocument);
                    messagexml = outStream.toByteArray();
                    logger.info("组装的认证请求报文为:\n" + outStream.toString());
                } catch (Exception e) {
                    isSuccess = false;
                    errDesc = "组装认证请求报文出现异常";
                    logger.error("组装认证请求报文出现异常 " + e.getMessage());
                    result.setSuccess(isSuccess);
                    result.setErrDesc(errDesc);
                    return result;
                }
            }
            // 创建与网关的HTTP连接，发送认证请求报文，并接收认证响应报文
            // 创建与网关的HTTP连接 开始
            int statusCode = 500;
            HttpClient httpClient = null;
            PostMethod postMethod = null;
            if (isSuccess) {
                // HTTPClient对象
                httpClient = new HttpClient();
                httpClient.setConnectionTimeout(1000*20);//20秒
                httpClient.setTimeout(1000*25);//25秒
                postMethod = new PostMethod(authURL);
                postMethod.setRequestHeader("Connection","close");
                // 设置报文传送的编码格式
                postMethod.setRequestHeader("Content-Type","text/xml;charset=UTF-8");
                // 设置发送认证请求内容开始
                postMethod.setRequestBody(new ByteArrayInputStream(messagexml));
                try {
                    URL url = protocol(authURL);
                    //  执行postMethod 发送通讯报文与网关通讯
                    statusCode = httpClient.executeMethod(postMethod);
                    if(url != null && "https".equals(url.getProtocol())){
                        Protocol.unregisterProtocol("https");
                    }
                } catch (Exception e) {
                    isSuccess = false;
                    errCode = String.valueOf(statusCode);
                    errDesc = "吉大正元网关请求出现异常:" + e.getMessage();
                    postMethod.releaseConnection();
                    httpClient.getHttpConnectionManager().closeIdleConnections(0);
                    httpClient = null ;
                    /*String errorJdkMess = errorJdkMess(e);
                    if(errorJdkMess != null){
                        errDesc = errorJdkMess;
                    }*/
                    logger.error(errDesc);
                    result.setSuccess(isSuccess);
                    result.setErrDesc(errDesc);
                    result.setErrCode(errCode);
                    return result;
                }
            }
            // 读取网关返回的认证响应报文
            ///StringBuffer respMessageData = new StringBuffer();
            String respMessageXml = null;
            if (isSuccess) {
                logger.info("读取网关返回的认证响应报文开始");
                // 当返回200或500状态时处理业务逻辑
                if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
                    // 从头中取出转向的地址
                    try {
                        // 接收通讯报文并处理开始
                        byte[] inputstr = postMethod.getResponseBody();
                        ByteArrayInputStream ByteinputStream = new ByteArrayInputStream(inputstr);
                        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                        int ch = 0;
                        try {
                            while ((ch = ByteinputStream.read()) != -1) {
                                int upperCh = (char) ch;
                                outStream.write(upperCh);
                            }
                        } catch (Exception e) {
                            isSuccess = false;
                            errDesc = e.getMessage();
                            result.setSuccess(isSuccess);
                            result.setErrDesc(errDesc);
                            return result;
                        }
                        if (isSuccess) {
                            // 200 表示返回处理成功
                            if (statusCode == HttpStatus.SC_OK) {
                                respMessageXml = new String(outStream.toByteArray(), "UTF-8");
                                logger.info("认证响应数据为:" + respMessageXml);
                            } else {
                                // 500 表示返回失败，发生异常
                                isSuccess = false;
                                errCode = String.valueOf(statusCode);
                                errDesc = new String(outStream.toByteArray());
                                logger.error("响应状态码500信息为:"+errDesc);
                                result.setSuccess(isSuccess);
                                result.setErrDesc(errDesc);
                                result.setErrCode(errCode);
                                return result;
                            }
                        }
                        // 接收通讯报文并处理结束
                    } catch (IOException e) {
                        isSuccess = false;
                        errCode = String.valueOf(statusCode);
                        errDesc = e.getMessage();
                        logger.error("读取网关返回的认证响应报文出现异常:" + errDesc);
                        result.setSuccess(isSuccess);
                        result.setErrDesc(errDesc);
                        result.setErrCode(errCode);
                        return result;
                    } finally {
                        if(httpClient != null){
                            postMethod.releaseConnection();
                            httpClient.getHttpConnectionManager().closeIdleConnections(0);
                        }
                    }
                } else {
                    logger.warn("the response code is not 200 or 500.");
                    isSuccess = false;
                    result.setSuccess(isSuccess);
                    result.setErrDesc("the response code is not 200 or 500.");
                    return result;
                }
            }
            // 服务端处理(解析网关返回的认证响应报文)
            Document respDocument = null;
            Element headElement = null;
            Element bodyElement = null;
            if (isSuccess) {
                //System.out.println("解析网关返回的认证响应报文开始");
                // 特殊字符'&'处理
                respMessageXml = respMessageXml.replaceAll("&", "&amp;");
                respDocument = DocumentHelper.parseText(respMessageXml);

                headElement = respDocument.getRootElement().element(JitConstant.CommonConstant.MSG_HEAD);
                bodyElement = respDocument.getRootElement().element(JitConstant.CommonConstant.MSG_BODY);
                // 解析报文头
                if (headElement != null) {
                    boolean state = Boolean.valueOf(
                            headElement.elementTextTrim(JitConstant.CommonConstant.MSG_MESSAGE_STATE));
                    if (state) {
                        isSuccess = false;
                        errCode = headElement.elementTextTrim(JitConstant.CommonConstant.MSG_MESSAGE_CODE);
                        errDesc = headElement.elementTextTrim(JitConstant.CommonConstant.MSG_MESSAGE_DESC);
                        logger.error("网关认证业务处理失败！" + errDesc);
                        result.setSuccess(isSuccess);
                        result.setErrDesc(errDesc);
                        result.setErrCode(errCode);
                        return result;
                    }
                }
            }
            if (isSuccess) {
                // 解析报文体
                // 解析认证结果集
                Element authResultElement = bodyElement.element(JitConstant.AuthConstant.MSG_AUTH_RESULT_SET)
                        .element(JitConstant.AuthConstant.MSG_AUTH_RESULT);
                isSuccess = Boolean.valueOf(authResultElement.attributeValue(JitConstant.AuthConstant.MSG_SUCCESS));
                if (!isSuccess) {
                    errCode = authResultElement.elementTextTrim(JitConstant.AuthConstant.MSG_AUTH_MESSSAGE_CODE);
                    errDesc = authResultElement.elementTextTrim(JitConstant.AuthConstant.MSG_AUTH_MESSSAGE_DESC);
                    logger.error("身份认证失败，失败原因：" + errDesc);
                    result.setSuccess(isSuccess);
                    result.setErrDesc(errDesc);
                    result.setErrCode(errCode);
                    return result;
                }
            }
            //结果处理
            if (isSuccess) {
                String accessControlResult = bodyElement.elementTextTrim("accessControlResult");
                logger.info("网关根据规则对该用户计算的访问控制结果:" + accessControlResult);
                // 设置返回认证结果信息
                result.setAccessControlResult(accessControlResult);
                if("Deny".equals(accessControlResult)){
                    isSuccess = false;
                    errCode = "-1";
                    errDesc = "该用户无权限访问此应用";
                    logger.error(errDesc);
                    result.setSuccess(isSuccess);
                    result.setErrDesc(errDesc);
                    result.setErrCode(errCode);
                    return result;
                } else {
                    // 解析用户属性列表
                    Element attrsElement = bodyElement.element(JitConstant.AuthConstant.MSG_ATTRIBUTES);
                    if (attrsElement != null) {
                        List namespacesElements = (List)attrsElement.elements(JitConstant.AuthConstant.MSG_ATTRIBUTE);
                        if (namespacesElements != null && namespacesElements.size() > 0) {
                            /*logger.info("属性个数：" + namespacesElements.size());
                            for (int i = 0; i < namespacesElements.size(); i++) {
                                String arrs = ((Element)namespacesElements.get(i))
                                        .attributeValue(JitConstant.AuthConstant.MSG_NAMESPACE);
                                logger.info(arrs);
                            }*/
                            Map certAttributeNodeMap = new HashMap();
                            Map childAttributeNodeMap = new HashMap();
                            Map umsAttributeNodeMap = new HashMap();
                            Map pmsAttributeNodeMap = new HashMap();
                            Map customAttributeNodeMap = new HashMap();
                            String[] keyes = new String[2];
                            if (attrsElement != null) {
                                List attributeNodeList = attrsElement.elements(JitConstant.AuthConstant.MSG_ATTRIBUTE);
                                for (int i = 0; i < attributeNodeList.size(); i++) {
                                    keyes = new String[2];
                                    Element userAttrNode = (Element) attributeNodeList.get(i);
                                    String msgParentName = userAttrNode
                                            .attributeValue(JitConstant.AuthConstant.MSG_PARENT_NAME);
                                    String name = userAttrNode
                                            .attributeValue(JitConstant.AuthConstant.MSG_NAME);
                                    String value = userAttrNode.getTextTrim();
                                    keyes[0] = name;
                                    childAttributeNodeMap.clear();
                                    String arrs = ((Element)namespacesElements.get(i))
                                            .attributeValue(JitConstant.AuthConstant.MSG_NAMESPACE);
                                    if (arrs.trim().equals(JitConstant.AuthConstant.KEY_NAMESPACE_CINAS)) {
                                        // 证书信息
                                        if (msgParentName != null && !msgParentName.equals("")) {
                                            keyes[1] = msgParentName;
                                            if (value != null && value.length() > 0) {
                                                childAttributeNodeMap.put(keyes,value);
                                            }
                                        } else {
                                            if (value != null && value.length() > 0) {
                                                certAttributeNodeMap.put(keyes,value);
                                            }
                                        }
                                        certAttributeNodeMap.putAll(childAttributeNodeMap);
                                    } else if (arrs.trim().equals(JitConstant.AuthConstant.KEY_NAMESPACE_UMS)) {
                                        // UMS信息
                                        if (msgParentName != null && !msgParentName.equals("")) {
                                            keyes[1] = msgParentName;
                                            if (value != null && value.length() > 0) {
                                                childAttributeNodeMap.put(keyes,value);
                                            }
                                        } else {
                                            if (value != null && value.length() > 0) {
                                                umsAttributeNodeMap.put(keyes,value);
                                            }
                                        }
                                        umsAttributeNodeMap.putAll(childAttributeNodeMap);
                                        //} else if (arrs.trim().contains(AuthConstant.KEY_NAMESPACE_PMS)) {
                                    } else if (arrs.trim().indexOf(JitConstant.AuthConstant.KEY_NAMESPACE_PMS) != -1) {
                                        // PMS信息
                                        if (msgParentName != null && !msgParentName.equals("")) {
                                            keyes[1] = msgParentName;
                                            if (value != null && value.length() > 0) {
                                                childAttributeNodeMap.put(keyes,value);
                                            }
                                        } else {
                                            if (value != null && value.length() > 0) {
                                                pmsAttributeNodeMap.put(keyes,value);
                                            }
                                        }
                                        pmsAttributeNodeMap.putAll(childAttributeNodeMap);
                                    } else if (arrs.trim().indexOf(JitConstant.AuthConstant.KEY_NAMESPACE_CUSTOM) != -1) {
                                        // 自定义信息
                                        if (msgParentName != null && !msgParentName.equals("")) {
                                            keyes[1] = msgParentName;
                                            if (value != null && value.length() > 0) {
                                                childAttributeNodeMap.put(keyes,value);
                                            }
                                        } else {
                                            if (value != null && value.length() > 0) {
                                                customAttributeNodeMap.put(keyes,value);
                                            }
                                        }
                                        customAttributeNodeMap.putAll(childAttributeNodeMap);
                                    } else {
                                        // 如果有其他的属性信息添加到证书信息里面
                                        if (msgParentName != null && !msgParentName.equals("")) {
                                            keyes[1] = msgParentName;
                                            if (value != null && value.length() > 0) {
                                                childAttributeNodeMap.put(keyes,value);
                                            }
                                        } else {
                                            if (value != null && value.length() > 0) {
                                                certAttributeNodeMap.put(keyes,value);
                                            }
                                        }
                                        certAttributeNodeMap.putAll(childAttributeNodeMap);
                                    }
                                }
                                // 设置返回认证结果信息
                                result.setCertAttributeNodeMap(certAttributeNodeMap);
                                result.setUmsAttributeNodeMap(umsAttributeNodeMap);
                                result.setPmsAttributeNodeMap(pmsAttributeNodeMap);
                                result.setCustomAttributeNodeMap(customAttributeNodeMap);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            isSuccess = false;
            errDesc = e.getMessage();
            logger.error(errDesc);
            result.setErrDesc(errDesc);
            result.setSuccess(isSuccess);
            return result;
        }
        result.setSuccess(isSuccess);
        logger.info("吉大正元网关认证成功.");
        return result;
    }

    /**
     * 密文方式发送请求前调用
     * @param authURL
     * @return
     */
    private static URL protocol(String authURL){
        // 发送原文请求报文与网关通讯
        URL url = getUrl(authURL);
        if(url != null && "https".equals(url.getProtocol())){
            int port = 443;
            if(url.getPort() != -1){
                port = url.getPort();
            }
            Protocol https = new Protocol("https", new HTTPSSecureProtocolSocketFactory(), port);
            Protocol.registerProtocol("https", https);
        }
        return url;
    }
    /**
     * 根据传入的url地址返回url对象
     * @param urlAddress
     * @return
     */
    private static URL getUrl(String urlAddress){
        URL url = null;
        try {
            url = new URL(urlAddress);
        } catch (MalformedURLException e) {
            logger.error(e.getMessage(),e);
        }
        return url;
    }
    /**
     * jdk版本支持校验
     * @param e
     * @return
     */
    private static String errorJdkMess(Exception e){
        String errDesc = null;
        //已测试jdk1.6和jdk1.7情况。
        if ("Received fatal alert: protocol_version".equals(e.getMessage()) ||
                "Remote host closed connection during handshake".equals(e.getMessage())) {
            float weight = Float.parseFloat(getJavaVersion());
            if (weight <= 1.7f) {
                errDesc = "当前运行的服务器jdk版本过低，需要升级jdk到1.8版本以上；或将网关SSL级别调整为低级";
                logger.error(errDesc);
            }
        }
        return errDesc;
    }
    /**
     * 获取当前运行jdk版本返回前两位
     * @return
     */
    private static String getJavaVersion(){
        String javaVersion = System.getProperty("java.version");
        String[] array = javaVersion.split("\\.");
        String newVersion = "";
        for (int i = 0; i < 2; i++) {
            newVersion += array[i];
            if(i == 0){
                newVersion += ".";
            }
        }
        return newVersion;
    }

    public static Map getConfigMap() {
        return configMap;
    }
}
